package com.xdf.whiteaccount.aop;

import com.xdf.whiteaccount.cloudentity.Mill;
import com.xdf.whiteaccount.cloudentity.UserMill;
import com.xdf.whiteaccount.cloudservice.MillService;
import com.xdf.whiteaccount.cloudservice.UserMillService;
import com.xdf.whiteaccount.config.datasource.DynamicDataSource;
import com.xdf.whiteaccount.entity.SysConfigVarchar;
import com.xdf.whiteaccount.enums.ConfigVarEnum;
import com.xdf.whiteaccount.enums.DatasourceKey;
import com.xdf.whiteaccount.utils.Example;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * @program: white-account
 * @description:
 * @author: 张柯
 * @create: 2021-07-27 16:46
 **/
@Component
@Slf4j
@Aspect
public class SysConfigVarcharServiceAspect extends AbstractAop {
    @Autowired
    private UserMillService userMillService;
    @Autowired
    private MillService millService;
    @Autowired
    private TransactionTemplate transactionTemplate;

    @Pointcut("execution(* com.xdf.whiteaccount.service.SysConfigVarcharService.update*(..))")
    public void cutUpdate() {
    }

    /**
     * 校验修改的染厂名是否重复
     *
     * @param joinPoint
     */
    @Before("cutUpdate()")
    public void beforeUpdate(JoinPoint joinPoint) throws Exception {
        Object param = getParam1(joinPoint);
        if (param instanceof SysConfigVarchar) {
            SysConfigVarchar record = (SysConfigVarchar) param;
            if (ConfigVarEnum.CLIENT_NICK_NAME.getField().equals(record.getConfigField())) {
                Mill  mill = millService.selectMillByBackendName(DynamicDataSource.getInstance().getCurrentDataSourceName());
                Long  count = millService.countByExample(new Example().andEq("sid", record.getConfigValue()));
                if (count > 0 && !mill.getSid().equals(record.getConfigValue())) {
                    throw new RuntimeException("当前设置的客户简称已经被使用，请更换其他名称！");
                }
            }
        }
    }

    /**
     * 修改配置执行
     *
     * @param joinPoint
     * @param result
     * @return
     */
    @AfterReturning(value = "cutUpdate()", returning = "result")
    public Object afterReturning(JoinPoint joinPoint, int result) throws Exception {
        if (result > 0) {
            if (getParam1(joinPoint) instanceof SysConfigVarchar) {
                SysConfigVarchar param = (SysConfigVarchar) getParam1(joinPoint);
                if (StringUtils.isNotEmpty(param.getConfigValue()) && ConfigVarEnum.CLIENT_NICK_NAME.getField().equals(param.getConfigField())) {
                    //  更改公司简称后自动更改云数据库上的染厂名
                    DynamicDataSource dataSource = DynamicDataSource.getInstance();
                    String dbName = dataSource.getCurrentDataSourceName();
                    //  切换数据源到主数据库,此处准备手动添加事务
                    dataSource.switchDataSource(DatasourceKey.PRIMARY_KEY);
                    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
                    transactionTemplate.executeWithoutResult(transactionStatus -> {
                        try {
                            Mill mill = millService.selectMillByBackendName(dbName);
                            //  判断如果有相同的染厂名不更改Mill
                            if (millService.countByExample(new Example().andEq("sid", param.getConfigValue())) > 0)
                                return;
                            if (mill == null) return;
                            //  更新染厂Mill
                            userMillService.updateByExample(
                                    UserMill.builder().millSid(param.getConfigValue()).build(),
                                    new Example().andEq("mill_sid", mill.getSid()));
                            millService.updateByPrimaryKeySelective(Mill.builder().iid(mill.getIid()).sid(param.getConfigValue()).build());
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    });
                    dataSource.switchDataSource(dbName);
                    return result;
                }
            }
        }
        return result;
    }
}